package com.easymin.weixin.common.api;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easymin.weixin.controller.v5.utils.ResultV5;

/**
 * 加油站API
 *
 * @author zane
 */
@Component
public class GasApi {

    private static final Logger logger = LoggerFactory.getLogger(DaijiaApi.class);

    @Value("${module.gas.url}")
    private String apiServer;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 构造请求路径
     *
     * @param api 接口地址
     * @return 请求路径
     */
    private String buildApi(String api) throws Exception {
        return buildApi(apiServer, api);
    }

    /**
     * 构造请求路径
     *
     * @param server 主机
     * @param api    接口地址
     * @return 请求路径
     */
    private String buildApi(String server, String api) throws Exception {
        if (server.endsWith("/") && api.startsWith("/")) {
            return server + api.substring(1, api.length());
        } else if (!server.endsWith("/") && !api.startsWith("/")) {
            return server + "/" + api;
        } else if (
                (server.endsWith("/") && !api.startsWith("/")) ||
                        (!server.endsWith("/") && api.startsWith("/"))) {
            return server + api;
        } else {
            logger.error("构造请求路径错误");
            throw new Exception("构造请求路径错误");
        }
    }

    /**
     * 构造代驾请求路径
     *
     * @param server 主机
     * @param api    接口地址
     * @return 请求路径
     */
    private String buildDaijiaApi(String server, String api) throws Exception {
        StringBuilder builder = new StringBuilder();

        String daijiaServer = StringUtils.trimToEmpty(server).toLowerCase();
        if (!daijiaServer.startsWith("http://") && !daijiaServer.startsWith("https://")) {
            builder.append("http://");
        }
        builder.append(daijiaServer);
        if (!daijiaServer.endsWith("/")) {
            builder.append("/");
        }

        if (StringUtils.isNotBlank(api)) {
            builder.append(api);
        }

        return builder.toString();
    }

    /**
     * get请求
     *
     * @param url    路径
     * @param params 参数
     * @return
     * @throws Exception
     */
    private String getRequest(String url, Map<String, Object> params) throws Exception {
        StringBuffer buffer = new StringBuffer();
        buffer.append(url);
        if (params != null && !params.isEmpty()) {
            buffer.append("?");
            for (String key : params.keySet()) {
                String value = String.valueOf(params.get(key));
                if (value != null && !value.equals("null") && !value.isEmpty()) {
                    buffer.append(key + "=" + value + "&");
                }
            }
        }
        String paramsStr = buffer.toString();
        paramsStr = paramsStr.substring(0, paramsStr.length() - 1);
        String api = buildApi(paramsStr);
        System.out.println("---------------------:" + api);
        String resp = restTemplate.getForObject(api, String.class, new Object[]{});
        return resp;
    }

    /**
     * get请求
     *
     * @param url    路径
     * @param params 参数
     * @return
     * @throws Exception
     */
    private String getNewRequest(String url, Map<String, Object> params) throws Exception {
        StringBuffer buffer = new StringBuffer();
        buffer.append(url);
        if (params != null && !params.isEmpty()) {
            buffer.append("?");
            for (String key : params.keySet()) {
                String value = String.valueOf(params.get(key));
                if (value != null && !value.equals("null") && !value.isEmpty()) {
                    buffer.append(key + "=" + value + "&");
                }
            }
        }
        String paramsStr = buffer.toString();
        String api = paramsStr.substring(0, paramsStr.length() - 1);
        System.out.println("---------------------:" + api);
        String resp = restTemplate.getForObject(api, String.class, new Object[]{});
        return resp;
    }

    /**
     * get请求,调用代驾使用
     *
     * @param url    路径
     * @param params 参数
     * @return
     * @throws Exception
     */
    private String getRequest(String url, String api, Map<String, Object> params) throws Exception {
        StringBuffer buffer = new StringBuffer();
        buffer.append(buildApi(url, api));
        if (params != null && !params.isEmpty()) {
            buffer.append("?");
            for (String key : params.keySet()) {
                String value = String.valueOf(params.get(key));
                if (value != null && !value.equals("null") && !value.isEmpty()) {
                    buffer.append(key + "=" + value + "&");
                }
            }
        }
        String path = buffer.toString();
        path = path.substring(0, path.length() - 1);
        System.out.println("path -- " + path);
        String resp = restTemplate.getForObject(path, String.class, new Object[]{});
        return resp;
    }

    /**
     * post请求
     *
     * @param url    路径
     * @param params 参数
     * @return
     * @throws Exception
     */
    private String postRequest(String url, MultiValueMap<String, String> params) throws Exception {
        String resp = restTemplate.postForObject(url, params, String.class);
        System.out.println(resp);
        return resp;
    }

    /**
     * 获取附近加油站
     *
     * @param brand     品牌
     * @param gasNum    油号
     * @param privilege 特权
     * @param lng       经度
     * @param lat       纬度
     * @param page      页码
     * @param rows      条数
     * @param appKey    系统key
     * @return ResultV5
     * @throws Exception 请求异常
     */
    public ResultV5 gasStationList(String brand,
                                   String gasNum,
                                   Boolean privilege,
                                   Double lng,
                                   Double lat,
                                   Integer page,
                                   Integer rows,
                                   String appKey) throws Exception {
        ResultV5 result = null;
        int code = 99;
        try {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("brand", brand);
            params.put("gasNum", gasNum);
            params.put("privilege", privilege);
            params.put("lng", lng);
            params.put("lat", lat);
            params.put("page", page);
            params.put("rows", rows);
            params.put("appKey", appKey);
            String resp = getRequest("api/gasstation/queryGasStation", params);
            JSONObject respData = JSONObject.parseObject(resp);
            code = respData.getIntValue("code");
            String message = respData.getString("message");

            if (code != 0) {
                result = new ResultV5(code, message);
                return result;
            }

            JSONObject data = respData.getJSONObject("data");
            result = new ResultV5(code, message);
            result.setData(data);
        } catch (Exception e) {
            // ignore
        }

        return result;
    }

    /**
     * 查询所有的加油站品牌
     *
     * @param appKey 系统key
     * @return ResultV5
     * @throws Exception 请求异常
     */
    public ResultV5 brands
    (String appKey)
            throws Exception {
        ResultV5 result = null;
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("appKey", appKey);
        String resp = getRequest("api/gasstation/queryBrand", params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONArray data = respData.getJSONArray("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }

    /**
     * 加油站详情[点击加油站列表时的跳转时使用此接口]
     *
     * @param id     加油站ID
     * @param appKey 系统Key
     * @return ResultV5
     * @throws Exception 请求异常
     */
    public ResultV5 stationInfo
    (Long id,
     String appKey)
            throws Exception {
        ResultV5 result = null;
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id", id);
        params.put("appKey", appKey);
        String resp = getRequest("api/gasstation/queryByGasStationId", params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONObject data = respData.getJSONObject("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }

    /**
     * 获取加油站评价
     *
     * @param gasId  加油站Id
     * @param appKey 系统Key
     * @param page   页码
     * @param rows   条数
     * @return ResultV5
     * @throws Exception
     */
    public ResultV5 reviews
    (Long gasId,
     String appKey,
     Integer page,
     Integer rows)
            throws Exception {
        ResultV5 result = null;
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("gasStationId", gasId);
        params.put("appKey", appKey);
        params.put("page", page);
        params.put("rows", rows);
        String resp = getRequest("api/review/queryByGasStationId", params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONObject data = respData.getJSONObject("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }

    /**
     * 支付加油站订单时的加油站及其客户优惠券的信息
     *
     * @param server       代驾服务地址
     * @param passengerId  客户ID
     * @param gasStationId 加油站ID
     * @param appKey       系统key
     * @return ResultV5
     * @throws Exception
     */
    public ResultV5 orderStationInfo
    (String server,
     Long passengerId,
     Long gasStationId,
     String appKey)
            throws Exception {
        ResultV5 result = null;
        String api = buildDaijiaApi(server, "passenger/api/rest/v4/gasstation/queryGasStationV5");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("passengerId", passengerId);
        params.put("gasStationId", gasStationId);
        params.put("timestamp", System.currentTimeMillis());
        params.put("appKey", appKey);

        String resp = getNewRequest(api, params);

        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONObject data = respData.getJSONObject("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }

    /**
     * 加油站订单余额支付
     *
     * @param server        代驾地址
     * @param passengerId   客户Id
     * @param gsId          加油站Id
     * @param gasNum        油号
     * @param money         加油金额
     * @param realMoney     实收金额
     * @param discountMoney 平台优惠
     * @param couponId      优惠券ID
     * @param compressorGun 服务号
     * @param appKey        系统key
     * @return ResultV5
     * @throws Exception
     */
    public ResultV5 paymentByBlance
    (String server,
     Long passengerId,
     Long gsId,
     String gasNum,
     BigDecimal money,
     BigDecimal realMoney,
     BigDecimal discountMoney,
     Long couponId,
     String compressorGun,
     String appKey)
            throws Exception {
        ResultV5 result = null;
        String api = buildDaijiaApi(server, "passenger/api/rest/v4/gasstation/paymentOrderV5");
        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("passengerId", String.valueOf(passengerId));
        params.add("gsId", String.valueOf(gsId));
        params.add("gasNum", gasNum);
        params.add("money", String.valueOf(money));
        params.add("realMoney", String.valueOf(realMoney));
        params.add("discountMoney", String.valueOf(discountMoney));
        if (couponId != null && !String.valueOf(couponId).isEmpty()) {
            params.add("couponId", String.valueOf(couponId));
        }
        if (compressorGun != null && !compressorGun.isEmpty()) {
            params.add("compressorGun", compressorGun);
        }
        params.add("payType", "balance");
        params.add("timestamp", String.valueOf(System.currentTimeMillis()));
        params.add("appKey", appKey);
        String resp = postRequest(api, params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONObject data = respData.getJSONObject("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }

    /**
     * 加油站订单微信支付
     *
     * @param server        代驾地址
     * @param passengerId   客户Id
     * @param openId        微信Id
     * @param gsId          加油站Id
     * @param gasNum        油号
     * @param money         加油金额
     * @param realMoney     实收金额
     * @param discountMoney 平台优惠
     * @param couponId      优惠券ID
     * @param compressorGun 服务号
     * @param appKey        系统key
     * @return
     * @throws Exception
     */
    public JSONObject paymentByWX
    (String server,
     Long passengerId,
     String openId,
     Long gsId,
     String gasNum,
     String compressorGun,
     BigDecimal money,
     BigDecimal realMoney,
     BigDecimal discountMoney,
     Long couponId,
     String appKey)
            throws Exception {
        String api = buildDaijiaApi(server, "passenger/api/rest/v4/gasstation/wx/prepayOrderV5");
        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("passengerId", String.valueOf(passengerId));
        params.add("openId", openId);
        params.add("gsId", String.valueOf(gsId));
        params.add("gasNum", String.valueOf(gasNum));
        params.add("money", String.valueOf(money));
        params.add("realMoney", String.valueOf(realMoney));
        params.add("discountMoney", String.valueOf(discountMoney));
        if (couponId != null && !String.valueOf(couponId).isEmpty()) {
            params.add("couponId", String.valueOf(couponId));
        }
        if (compressorGun != null && !compressorGun.isEmpty()) {
            params.add("compressorGun", compressorGun);
        }
        params.add("timestamp", String.valueOf(System.currentTimeMillis()));
        params.add("appKey", appKey);
        String resp = postRequest(api, params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        if (code != 0) {
            return null;
        }
        JSONObject data = respData.getJSONObject("data");
        return data;
    }

    /**
     * 客户订单列表
     *
     * @param passengerId 客户Id
     * @param page        页码
     * @param rows        条数
     * @param appKey      系统key
     * @return ResultV5
     * @throws Exception
     */
    public ResultV5 orders
    (Long passengerId,
     Integer page,
     Integer rows,
     String appKey)
            throws Exception {
        if (page <= 0) {
            page = 1;
        }
        ResultV5 result = null;
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("passengerId", passengerId);
        params.put("page", page);
        params.put("rows", rows);
        params.put("appKey", appKey);
        String resp = getRequest("api/order/queryByPassengerId", params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONObject data = respData.getJSONObject("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }

    /**
     * 订单信息
     *
     * @param id     订单Id
     * @param appKey 系统key
     * @return ResultV5
     * @throws Exception
     */
    public ResultV5 order
    (Long id,
     String appKey)
            throws Exception {
        ResultV5 result = null;
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("id", id);
        params.put("appKey", appKey);
        String resp = getRequest("api/order/queryById", params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONObject data = respData.getJSONObject("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }

    /**
     * 订单评价
     *
     * @param gasStationId   加油站Id
     * @param gasStationName 加油站名称
     * @param orderNo        订单号
     * @param serviceNo      服务号
     * @param clientName     客户姓名
     * @param clientPhone    客户电话
     * @param clientPhoto    客户头像
     * @param score          评分
     * @param content        内容
     * @param appKey         系统key
     * @return ResultV5
     * @throws Exception
     */
    public ResultV5 review
    (Long gasStationId,
     String gasStationName,
     String orderNo,
     String serviceNo,
     String clientName,
     String clientPhone,
     String clientPhoto,
     Double score,
     String content,
     String appKey)
            throws Exception {
        ResultV5 result = null;
        String api = buildApi("api/review/review");
        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("gasStationId", String.valueOf(gasStationId));
        params.add("gasStationName", gasStationName);
        params.add("orderNo", orderNo);
        params.add("serviceNo", serviceNo);
        params.add("clientName", clientName);
        params.add("clientPhone", clientPhone);
        params.add("clientPhoto", clientPhoto);
        params.add("score", String.valueOf(score));
        params.add("content", content);
        params.add("appKey", appKey);
        String resp = postRequest(api, params);
        JSONObject respData = JSONObject.parseObject(resp);
        int code = respData.getIntValue("code");
        String message = respData.getString("message");
        if (code != 0) {
            result = new ResultV5(code, message);
            return result;
        }
        JSONObject data = respData.getJSONObject("data");
        result = new ResultV5(code, message);
        result.setData(data);
        return result;
    }
}
